package com.zhiche.lisa.bms.service.utils.common.identityCodeUtil.impl;

import com.baomidou.mybatisplus.enums.SqlLike;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.google.common.base.Strings;
import com.zhiche.lisa.bms.dao.model.increment.IncrementCode;
import com.zhiche.lisa.bms.service.increment.IncrementCodeService;
import org.apache.commons.lang3.StringUtils;

import java.util.Calendar;
import java.util.Map;

/**
 * @Author: liuanshun
 * @Description:
 * @Date: Create in 15:07 2018/11/16
 */
public class IncrementServiceCode extends ServiceCode<IncrementCodeService> {
    private final String CODE_TYPE_NAME;
    private final String CODE_CLOUMN_NAME = "increment_code";

    /**
     * 初始化构造
     *
     * @param importService
     * @param codeFactory
     * @param codeTypeName
     */
    public IncrementServiceCode(IncrementCodeService importService, String codeFactory, String codeTypeName) {
        super(importService, codeFactory);
        CODE_TYPE_NAME = codeTypeName;
    }

    /**
     * 初始化id自增号
     *
     * @return
     */
    @Override
    public IncrementServiceCode init() {
        super.init();
        return this;
    }

    /**
     * 格式化映射数据
     */
    @Override
    protected void factoryDateMapping() {
        Calendar instance = Calendar.getInstance();
        mapper.put("yyyy", String.format("%04d", instance.get(Calendar.YEAR)));
        mapper.put("MM", String.format("%02d", instance.get(Calendar.MONTH) + 1));
        mapper.put("dd", String.format("%02d", instance.get(Calendar.DAY_OF_MONTH)));
    }

    /**
     * 自主检测映射数据
     *
     * @return
     */
    @Override
    protected boolean checkDateMapping() {
        Calendar instance = Calendar.getInstance();
        if (!String.format("%04d", instance.get(Calendar.YEAR)).equals(mapper.get("yyyy"))) {
            return false;
        }
        if (!String.format("%02d", instance.get(Calendar.MONTH) + 1).equals(mapper.get("MM"))) {
            return false;
        }
        if (!String.format("%02d", instance.get(Calendar.DAY_OF_MONTH)).equals(mapper.get("dd"))) {
            return false;
        }
        return true;
    }

    /**
     * 获取下一个code
     *
     * @param valueMapping 动态映射字符（传入以格式定义关键字为key的映射值）
     * @return 转换后的code结果
     */
    @Override
    public String getNextCode(Map<String, String> valueMapping) {
        String nextCode = super.getNextCode(codeFactory, valueMapping);
        synchroIncrementId(nextCode);
        return nextCode;
    }

    /**
     * 获取之前跌增的id（由数据库寻找）
     *
     * @return 存在结果的String类型id结果，或者是不存在结果的null
     */
    @Override
    protected Integer getAfterInitId() {
        String checkChar = CHECK_STR;
        if (!Strings.isNullOrEmpty(checkChar)) {
            String notIncrementStr = getNextCode(checkChar, null);
            Long maxId = getEwMaxId(notIncrementStr);
            if (maxId != null) {
                IncrementCode incrementCode = importService.selectById(maxId);
                String code = incrementCode.getIncrementCode();
                if (code.length() > notIncrementStr.length()) {
                    int i = code.indexOf(notIncrementStr);
                    if (i >= 0) {
                        String codeIncrement = code.substring(i + notIncrementStr.length());
                        if (StringUtils.isNumeric(codeIncrement)) {
                            return Integer.valueOf(codeIncrement);
                        }
                    }
                }
            }
        }
        return null;
    }

    private Long getEwMaxId(String notIncrementStr) {
        EntityWrapper<IncrementCode> entityWrapper = new EntityWrapper<>();
        entityWrapper.setSqlSelect("id");
        entityWrapper.orderBy("id desc");
        entityWrapper.eq("code_type_name", CODE_TYPE_NAME);
        entityWrapper.like(CODE_CLOUMN_NAME, "%" + notIncrementStr + "%", SqlLike.CUSTOM);

        return (Long) importService.selectObj(entityWrapper);
    }

    private void synchroIncrementId(String nextCode) {
        IncrementCode incrementCode = new IncrementCode();
        incrementCode.setId(null);
        incrementCode.setCodeTypeName(CODE_TYPE_NAME);
        incrementCode.setIncrementCode(nextCode);

        String checkChar = CHECK_STR;
        if (!Strings.isNullOrEmpty(checkChar)) {
            String notIncrementStr = getNextCode(checkChar, null);
            Long ewMaxId = getEwMaxId(notIncrementStr);

            if (ewMaxId != null) {
                incrementCode.setId(ewMaxId);
                importService.updateById(incrementCode);
            } else {
                importService.insert(incrementCode);
            }
        }
    }
}
